/* 此为监测服务，用于定时请求后台，目前主要用于监测登录情况
 */
import Vue, { ref } from 'vue';
import { MonitorApiService } from '../api/services/MonitorApiService';
import { isNullOrWhiteSpece } from '../utils/common';

class StateEntity {
  // 请求开始时间
  startTime: number = null;
  // 请求耗时
  useTime: number | null = null;
  // 服务器状态
  serverStatus: 'good' | 'busy' | 'disable' = null;
  // 不可用状态的连续次数；
  unUsedTime = 0;
}

export const MontiorState = ref<StateEntity>(new StateEntity());

export class MonitorService {
  src: MonitorApiService;
  interval: any;
  t = 6000;
  params: Array<{ Key: string; Value: string }>;
  cbs: Array<{ key: string; cb: (param?) => any }>;
  config: { goodTime: number; busyTime: number } = {
    goodTime: 1500,
    busyTime: 5000
  };

  // 默认时间为1分钟
  constructor(config?) {
    this.interval = null;
    this.params = [];
    this.cbs = [];
    this.src = new MonitorApiService();
    if (config && config.goodTime) {
      this.config.goodTime = config.goodTime;
    }
    if (config && config.busyTime) {
      this.config.busyTime = config.busyTime;
    }
  }

  setTime(time: number) {
    this.t = time;
  }

  open() {
    if (this.interval) {
      return;
    }
    this.interval = setInterval(this.runOnce.bind(this), this.t);
  }

  runOnce() {
    // 开始时间
    const startTime = new Date().getTime();
    // 设置 10秒超时
    let time = setTimeout(() => {
      time = null;
    }, 10000);
    this.src
      .Monitor(this.params, {})
      .then((res) => {
        this.cbs.forEach((callBackFunction) => {
          const r = res.find((o) => {
            return o.Key === callBackFunction.key;
          });
          if (r) {
            callBackFunction.cb(r);
          }
        });

        this.handleUpdateServerStatus(startTime);
      })
      .catch((err) => {
        console.log(err);
        this.handleUpdateServerStatus(startTime, true);
      });
  }

  /**
   * 更新服务器状态
   * @param startTime
   * @param isFail
   */
  handleUpdateServerStatus(startTime, isFail = false) {
    // 如果已经有更新的状态 则跳出
    if (startTime < MontiorState.value.startTime) {
      return;
    }
    MontiorState.value.useTime = new Date().getTime() - startTime;

    let status;
    if (isFail) {
      status = 'disable';
    } else if (MontiorState.value.useTime < this.config.goodTime) {
      status = 'good';
    } else if (MontiorState.value.useTime < this.config.busyTime) {
      status = 'busy';
    } else {
      status = 'disable';
    }

    if (status === 'disable') {
      MontiorState.value.unUsedTime++;
    } else {
      MontiorState.value.unUsedTime = 0;
    }

    MontiorState.value.serverStatus = status;
  }

  close() {
    if (this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    }
  }

  /**
   * 添加请求参数
   * @param {*} key
   * @param {*} obj
   */
  addParam(key: string, obj) {
    if (isNullOrWhiteSpece(key)) {
      console.error('heartbeat key cannot null');
      return;
    }
    const entity = this.params.find((o) => {
      return o.Key === key;
    });
    if (entity) {
      entity.Value = obj;
    } else {
      this.params.push({
        Key: key,
        Value: obj
      });
    }
  }

  removeParam(key: string) {
    if (isNullOrWhiteSpece(key)) {
      console.error('heartbeat key cannot null');
      return;
    }
    const index = this.params.findIndex((o) => {
      return o.Key === key;
    });
    if (index >= 0) {
      this.params.splice(index, 1);
    }
  }

  addCb(key, cb) {
    const entity = this.cbs.find((o) => {
      return o.key === key;
    });
    if (entity) {
      entity.cb = cb;
    } else {
      this.cbs.push({
        key,
        cb
      });
    }
  }

  removeCb(key) {
    const index = this.cbs.findIndex((o) => {
      return o.key === key;
    });
    if (index >= 0) {
      this.cbs.splice(index, 1);
    }
  }
}
